home *** CD-ROM | disk | FTP | other *** search
/ Shareware Grab Bag / Shareware Grab Bag.iso / 007 / tsr25src.arc / WATCH.ASM < prev   
Assembly Source File  |  1987-06-02  |  14KB  |  413 lines

  1. ;WATCH.ASM
  2. ;resident routine watches programs going resident
  3. ;and keeps a list of changes in interrupt vectors to an internal data structure
  4. ; written to use MicroSoft MASM version 4
  5. ; written by Kim Kokkonen, TurboPower Software
  6. ;
  7. ; VERSION 2.2  3/4/87
  8. ;   First release, version to be consistent with MAPMEM.PAS
  9. ; VERSION 2.3  5/1/87
  10. ;   Sets up a separate stack for the interrupt handlers
  11. ;     to solve problem first noticed with EMMCACHE and WATCH
  12. ;   Changes approach - store all vector information in RAM buffers
  13. ;   No disk access at all by WATCH
  14. ;   Better check for multiple installation
  15. ;   Changed to use MASM
  16. ; VERSION 2.4  5/17/87
  17. ;   for consistency with RELEASE
  18. ; VERSION 2.5  5/28/87
  19. ;   save flags in int21 handler
  20. ;
  21.  
  22. Cseg      segment public para
  23.           assume  cs:Cseg, ds:nothing, es:nothing, ss:nothing
  24.  
  25.           org     080H
  26. cmdline   label   byte                 ;pointer to command line
  27.  
  28.           org     100H
  29. comentry: jmp     init
  30.  
  31. ;******************************************************************************
  32. ;resident data section follows
  33. ;******************************************************************************
  34.  
  35. ;put the following in the MAP file
  36. public bmesg,origv,prevv,vpos,vchg
  37.  
  38. ;resident data structures not part of COM file
  39. vchg           equ     220H            ;location of data area (>= offset bmesg)
  40. vrecsize       equ     8               ;number of bytes per vector change record
  41. vsize          equ     80H*vrecsize    ;size of vector change area in bytes
  42.                                        ;space for 128 changes of vector here
  43.  
  44. ;vector table buffers
  45. origv          equ     vchg+vsize      ;location of original vector table
  46. veclen         equ     400H            ;size of vector table in bytes
  47. prevv          equ     origv+veclen    ;location of current vector table
  48. newstackpos    equ     prevv+veclen    ;location of newstack
  49. ssize          equ     0080H           ;number of bytes in temporary stack
  50. newloc         equ     newstackpos+ssize ;location for relocated installation code
  51.  
  52.                even
  53. vpos           dw      0               ;next position to write in data area
  54.  
  55. ;temporary stack used by interrupt handler
  56. newss          dw      0               ;segment of our temporary stack
  57. newsp          dw      0               ;initial stack pointer
  58.  
  59. ;information saved about the calling program
  60. oldss          dw      ?               ;stack segment
  61. oldsp          dw      ?               ;stack pointer
  62. curpsp         dw      ?               ;program segment
  63.  
  64. ;id code for a PSP data block
  65. pspid          equ     0FFFFH          ;id used to indicate a PSP block
  66. ;int16H function call for id check
  67. getid          equ     'wa'            ;function code for int16
  68. chkid          equ     'WA'            ;returned by int16 getid check
  69.  
  70. ;previous interrupt handlers
  71. kbd_int        label dword
  72. old16          dw 2 dup (?)            ;old int16 vector
  73. dos_int        label dword
  74. old21          dw 2 dup (?)            ;old int21 vector
  75. tsr_int        label dword
  76. old27          dw 2 dup (?)            ;old int27 vector
  77.  
  78. ;***********************************************************************
  79. ;interrupt handler for int16
  80. ;used only to avoid reinstallation
  81. newint16 proc  near
  82.          assume ds:nothing
  83.          pushf                  ;save application flags
  84.          sti
  85.          cmp    ax,getid        ;see if our id function
  86.          jne    ex16            ;no, pass on to previous int16
  87.  
  88.          mov    ax,chkid        ;return id code
  89.          popf
  90.          iret                   ;back to caller
  91.  
  92. ex16:    popf
  93.          jmp    kbd_int         ;transfer control to the previous int16
  94. newint16 endp
  95.  
  96. ;***********************************************************************
  97. ;interrupt handler for int21
  98. newint21 proc  near
  99.          assume ds:nothing
  100.          pushf                  ;save flags
  101.          cmp    ah,31H
  102.          jne    ex21
  103.          call   checkvec        ;call routine to check vector table
  104. ex21:    popf
  105.          jmp    dos_int         ;transfer control to the previous int21 vector
  106. newint21 endp
  107.  
  108. ;***********************************************************************
  109. ;interrupt handler for int27
  110. newint27 proc  near
  111.          assume ds:nothing
  112.          call   checkvec
  113. ex27:    jmp    tsr_int         ;transfer control to the previous int27 vector
  114. newint27 endp
  115.  
  116. ;***********************************************************************
  117. ;procedure checkvec
  118. ;  compares vectors to previous installation
  119. ;  stores a new vector buffer
  120. ;  writes information to wfile
  121.  
  122. checkvec proc  near
  123.        assume ds:nothing
  124.  
  125. ;save current stack
  126.        mov     oldss,ss
  127.        mov     oldsp,sp
  128.  
  129. ;switch to our stack
  130.        cli
  131.        mov     ss,newss
  132.        mov     sp,newsp
  133.        sti
  134.  
  135. ;store registers
  136.        push    ax
  137.        push    bx
  138.        push    cx
  139.        push    dx
  140.        push    si
  141.        push    di
  142.        push    ds
  143.        push    es
  144.  
  145. ;get DS set up as CS
  146.        mov     ax,cs
  147.        mov     ds,ax
  148.        assume  ds:cseg
  149.  
  150.        mov     ah,51H           ;get current PSP
  151.        pushf
  152.        call    dos_int          ;bx returns PSP
  153.  
  154.        call    vechdr           ;store the PSP segment of the program going resident
  155.        call    cmpvec           ;scan the vector table looking for changes from our buffer
  156.        mov     di,prevv         ;save the new version of the vector table
  157.        call    savevec
  158.  
  159. ;restore registers
  160.        pop     es
  161.        pop     ds
  162.        assume  ds:nothing
  163.        pop     di
  164.        pop     si
  165.        pop     dx
  166.        pop     cx
  167.        pop     bx
  168.        pop     ax
  169.  
  170. ;restore stack
  171.        cli
  172.        mov     ss,oldss
  173.        mov     sp,oldsp
  174.        sti
  175.  
  176.        ret
  177. checkvec endp
  178.  
  179. ;**************************************************************************
  180. ;procedure vechdr
  181. ;  writes a header to the vector data area for this new TSR
  182. ;  on entry:
  183. ;    bx has PSP of the new TSR
  184. ;
  185. vechdr proc near
  186.        assume ds:cseg
  187.        cmp      vpos,vsize-vrecsize       ;assure room for next record
  188.        ja       vecex                     ;ignore if no room
  189.  
  190.        push     di
  191.        mov      di,vpos                   ;index into vchg array
  192.        mov      word ptr [di+vchg],pspid  ;store id word
  193.        mov      word ptr [di+vchg+2],bx   ;store PSP value
  194.                                           ;two words in record left unitialized
  195.        add      vpos,vrecsize             ;move to next data element
  196.        pop      di
  197.  
  198. vecex: ret
  199. vechdr endp
  200.  
  201. ;**************************************************************************
  202. ;procedure wrchg
  203. ;  writes information about changed vectors to the data area
  204. ;  on entry
  205. ;    ax has changed vector number
  206. ;    ds points to segment 0
  207. ;  on exit:
  208. ;    flags changed
  209. ;
  210. wrchg  proc     near
  211.        assume   ds:nothing, es:nothing
  212.        cmp      vpos,vsize-vrecsize ;assure room for next record
  213.        ja       wrcex
  214.  
  215.        push     ax
  216.        push     si
  217.        push     di
  218.  
  219.        mov      di,vpos             ;index into vchg array
  220.        mov      cs:[di+vchg],ax     ;store interrupt vector number
  221.  
  222.        mov      si,ax
  223.        shl      si,1
  224.        shl      si,1                ;get address of vector
  225.        mov      ax,[si]             ;get offset of vector
  226.        mov      cs:[di+vchg+2],ax   ;store vector offset
  227.        mov      ax,[si+2]           ;get segment
  228.        mov      cs:[di+vchg+4],ax   ;store segment
  229.                                     ;one word in record left unused
  230.        add      vpos,vrecsize       ;move to next data element
  231.  
  232.        pop      di
  233.        pop      si
  234.        pop      ax
  235.  
  236. wrcex: ret
  237. wrchg  endp
  238.  
  239. ;**************************************************************************
  240. ;procedure cmpvec
  241. ;  compares vectors in buffer to those in use
  242. ;  writes numbers of those different to data area
  243. ;  on exit:
  244. ;    ax,si,di destroyed
  245. ;    flags changed
  246. ;
  247. cmpvec  proc   near
  248.         assume ds:nothing, es:nothing
  249.         push    ds
  250.         push    es
  251.  
  252.         xor     si,si           ;source offset 0
  253.         mov     ds,si           ;source address segment 0
  254.         mov     ax,cs
  255.         mov     es,ax
  256.         xor     ax,ax           ;vector counter
  257.         mov     di,prevv        ;destination offset
  258.         cld                     ;upward direction
  259.  
  260. nexvec: cmpsw                   ;compare offsets
  261.         je      cmpseg          ;compare segments if offsets equal
  262.         call    wrchg           ;write changed vector
  263.         cmpsw                   ;compare next word, ignore result
  264.         jmp short vecinc
  265.  
  266. cmpseg: cmpsw                   ;compare segments
  267.         je      vecinc
  268.         call    wrchg           ;write changed vector
  269.  
  270. vecinc: inc     ax              ;next vector number
  271.         cmp     ax,00FFH
  272.         jbe     nexvec          ;continue until 256 vectors checked
  273.  
  274.         pop     es
  275.         pop     ds
  276.         ret
  277. cmpvec  endp
  278.  
  279. ;**************************************************************************
  280. ;procedure savevec
  281. ;  saves image of interrupt vectors
  282. ;  on entry:
  283. ;    di has destination offset
  284. ;  on exit:
  285. ;    ax,cx,si,di destroyed
  286. ;    flags changed
  287. ;
  288. savevec proc   near
  289.         assume ds:nothing, es:nothing
  290.         push    ds
  291.         push    es
  292.         xor     si,si           ;offset 0
  293.         mov     ds,si           ;source address segment 0
  294.         mov     ax,cs
  295.         mov     es,ax           ;destination always in this code segment
  296.         mov     cx,200H         ;512 integers to store
  297.         cld                     ;copy up
  298.         rep     movsw           ;copy vectors to our table
  299.         pop     es
  300.         pop     ds
  301.         ret
  302. savevec endp                    ;of proc savevec
  303.  
  304.  
  305. ;**************************************************************************
  306. ;resident portion above, temporary portion below
  307. ;**************************************************************************
  308.  
  309. ;temporary strings
  310.                even
  311. bmesg   db     13,10,'Cannot install WATCH more than once....',13,10,36
  312. mesg    db     13,10,'WATCH 2.5 successfully installed',13,10,36
  313. pname   db     'TSR WATCHER'
  314. plen    equ    $-pname             ;length of string
  315.  
  316. ;**************************************************************************
  317. ;install new handlers for DOS go-resident services
  318. init    proc   near
  319.         assume ds:cseg
  320.  
  321. ;use int 16h test to check for previous installation
  322.         mov     ax,getid        ;int16h diagnostic request
  323.         int     16h             ;now, ax=chkid if installed
  324.         cmp     ax,chkid        ;TSR already installed?
  325.         jne     success         ;no - jump if not installed
  326.  
  327. ;error exit
  328.         mov    dx,offset bmesg  ;error message
  329.         mov    ah,09H
  330.         int    21H              ;DOS print string
  331.         mov    ax,4C01H         ;exit with error
  332.         int    21H
  333.  
  334. ;print a success message
  335. success: mov    dx,offset mesg  ;start of message to write
  336.          mov    ah,09H
  337.          int    21H             ;DOS print string
  338.  
  339. ;relocate ourselves out of the way of the vector tables
  340.         mov     ax,cs
  341.         mov     es,ax
  342.         mov     di,newloc+10H
  343.         push    di                    ;will act as a return address
  344.         mov     si,offset newstk
  345.         mov     cx,lastcode-newstk
  346.         rep     movsb                 ;move code
  347.         ret                           ;"return" to the relocated code
  348.  
  349. ;initialize location of WATCH stack
  350. newstk: mov     newsp,newstackpos+ssize
  351.         mov     newss,cs        ;stack seg is code seg
  352.  
  353. ;get int 16H vector
  354.         mov    ax,3516H         ;GetVector DOS function call
  355.         int    21H
  356.         mov    old16,bx         ;store first word of old21
  357.         mov    old16[2],es      ;store second word
  358.  
  359. ;get int 21H vector
  360.         mov    ax,3521H         ;GetVector DOS function call
  361.         int    21H
  362.         mov    old21,bx         ;store first word of old21
  363.         mov    old21[2],es      ;store second word
  364.  
  365. ;get int 27H vector
  366.         mov    ax,3527H         ;GetVector DOS function call
  367.         int    21H
  368.         mov    old27,bx         ;store first word of old27 (offset)
  369.         mov    old27[2],es      ;store second word (segment)
  370.  
  371. ;put an id label at offset 80H to allow other programs to recognize WATCH
  372.         mov    ax,cs
  373.         mov    es,ax
  374.         mov    cx,plen          ;length of name string
  375.         mov    si,offset pname  ;offset of name string
  376.         mov    di,offset cmdline ;offset of DOS command line
  377.         cld                     ;transfer in forward direction
  378.         mov    al,cl
  379.         stosb                   ;store length byte first
  380.         rep    movsb            ;transfer characters
  381.  
  382. ;store image of original vector table (overwrites messages)
  383.         mov    di,origv
  384.         mov    ax,offset savevec
  385.         call   ax               ;absolute call works as code is moved
  386.  
  387. ;store it again into the current vector table
  388.         mov    di,prevv
  389.         mov    ax,offset savevec
  390.         call   ax               ;absolute call works as code is moved
  391.  
  392. ;install the new vectors
  393.         mov    ax,2516H
  394.         mov    dx,offset newint16
  395.         int    21H
  396.         mov    ax,2521H
  397.         mov    dx,offset newint21
  398.         int    21H
  399.         mov    ax,2527H
  400.         mov    dx,offset newint27
  401.         int    21H
  402.  
  403. ;terminate and stay resident
  404.         mov    dx,(newloc+15) shr 4
  405.         mov    ax,3100H        ;return success code
  406.         int    21H
  407.  
  408. lastcode:
  409. init    endp
  410.  
  411. Cseg    ends
  412.         end     ComEntry
  413.